<template>
	<view class="e-row" :id="elId" ref="rowRef" :style="[rowStyle]" @tap="clickHandler">
		<slot />
	</view>
</template>
<script lang="ts">
	import { defineComponent } from 'vue'
	import mpMixin from "../../libs/mixin/mpMixin";
	/**
	 * Row 栅格系统中的行
	 * @description 通过基础的 12 分栏，迅速简便地创建布局 
	 * @tutorial https://www.uviewui.com/components/layout.html
	 * @property {String | Number}	gutter		栅格间隔，左右各为此值的一半，单位px  (默认 0 )
	 * @property {String}			justify		水平排列方式(微信小程序暂不支持) 可选值为`start`(或`flex-start`)、`end`(或`flex-end`)、`center`、`around`(或`space-around`)、`between`(或`space-between`)  (默认 'start' )
	 * @property {String}			align		垂直排列方式 (默认 'center' )
	 * @property {Object}			customStyle	定义需要用到的外部样式
	 * 
	 * @event {Function} click row被点击
	 * @example <e-row justify="space-between" customStyle="margin-bottom: 10px"></e-row>
	 */
	export default defineComponent({
		name: "e-row",
		mixins: [mpMixin],
	});
</script>
<script setup lang="ts">
	import {
		ref,
		reactive,
		computed,
		getCurrentInstance,
		toRefs,
		provide
	} from 'vue'
	import {
		useDefaultProps
	} from '../../libs/hooks'
	import {
		rowProps,
		rowEmits
	} from './props';
	import { rowContextKey } from '../../libs/tokens'
	import {
		addStyle,
		addUnit
	} from "../../libs/utils/_utils";
	import {
		deepMerge,
		sleep,
		nanoid,
		getRect,
		getNvueRect,
	} from "../../libs/utils";
	import type {
		StyleProperties
	} from '../../libs/tokens'
	import componentsProps, {
		type DefaultProps
	} from "../../libs/config/componentsProps";


	const {
		row: rowDefaultProps
	} = toRefs(componentsProps);

	const _props = defineProps(rowProps)

	const props = useDefaultProps<DefaultProps['row']>(_props, rowDefaultProps);
	const emit = defineEmits(rowEmits)

	const ctx = getCurrentInstance()

	const elId = nanoid(21, true)
	const rowRef = ref()


	const eJustify = computed(() => {
		if (props.value.justify == 'end' || props.value.justify == 'start') return 'flex-' + props.value.justify
		else if (props.value.justify == 'around' || props.value.justify == 'between') return 'space-' + props.value.justify
		else return props.value.justify
	})
	const eAlignItem = computed(() => {
		if (props.value.align == 'top') return 'flex-start'
		if (props.value.align == 'bottom') return 'flex-end'
		else return props.value.align
	})

	const rowStyle = computed(() => {
		const style : StyleProperties = {
			alignItems: eAlignItem.value,
			justifyContent: eJustify.value
		}
		// 通过给e-row左右两边的负外边距，消除e-col在有gutter时，第一个和最后一个元素的左内边距和右内边距造成的影响
		if (props.value.gutter) {
			style.marginLeft = addUnit(-Number(props.value.gutter) / 2)
			style.marginRight = addUnit(-Number(props.value.gutter) / 2)
		}
		return deepMerge(style, addStyle(props.value.customStyle as string))
	})

	const clickHandler = () => {
		emit('click')
	}

	const width = ref(0)
	const getComponentWidth = async () => {
		// 延时一定时间，以确保节点渲染完成
		await sleep()
		return new Promise(resolve => {
			// uView封装的获取节点的方法，详见文档
			// #ifndef APP-NVUE
			getRect(ctx, `#${elId}`).then(res => {
				width.value = res.width!
			})
			// #endif
			// #ifdef APP-NVUE
			// nvue的dom模块用于获取节点
			getNvueRect(rowRef.value).then(res => {
				width.value = res.width!
			})
			// #endif
		})
	}

	provide(rowContextKey, reactive({
		props,
		width,
		getComponentWidth
	}))
</script>
<style lang="scss" scoped>
	@import "../../libs/theme/row.scss";
</style>